package com.jinanzhuan.sqlciphertest;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.crypto.KeyGenerator;

public class KeyStoreTestActivity extends AppCompatActivity {
    private EditText contentText;
    private EditText etAlias;
    private SharedPreferences preferences;
    private AndroidEncryptUtils encryptUtils;
    private String alias = "AESGCMKEY";
    private static final String AndroidKeyStore = "AndroidKeyStore";

    public static void actionStart(Context context) {
        Intent intent = new Intent(context, KeyStoreTestActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_keystore_test);

        contentText = findViewById(R.id.et_input);
        etAlias = findViewById(R.id.et_alias);

        initSP();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            initEncrypt(alias);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void initEncrypt(String alias) {
        encryptUtils = new AndroidEncryptUtils();
        //Key key = getEncryptKeyFromStore("alias");
        //Log.e("TAG", "key: "+ key.getAlgorithm()+" class: "+key);
        encryptUtils.initGCM(getEncryptKeyFromStore(alias), null);
    }

    private void initSP() {
        preferences = getSharedPreferences("keystore", Context.MODE_PRIVATE);
    }

    public void saveData(View view) {
        String alias = etAlias.getText().toString().trim();
        if(!TextUtils.isEmpty(alias)) {
            this.alias = alias;
            initEncrypt(alias);
        }
        String content = contentText.getText().toString().trim();
        Log.e("TAG", "want to save content: "+content);
        String aesEncrypt = encryptUtils.aesEncrypt(content, 1);
        //String aesEncrypt = encryptUtils.encryptText(content);
        Log.e("TAG", "encrypt content: "+aesEncrypt);
        preferences.edit().putString("password_keystore", aesEncrypt).commit();

    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void getData(View view) {
        String alias = etAlias.getText().toString().trim();
        if(!TextUtils.isEmpty(alias)) {
            this.alias = alias;
            initEncrypt(alias);
        }
        String password = preferences.getString("password_keystore", "");
        Log.e("TAG", "get data from sp password: "+password);
        String decrypt = encryptUtils.aesDecrypt(password, getEncryptKeyFromStore(this.alias),1);
        Log.e("TAG", "decrypt password: "+decrypt);
        //byte[] content = encryptUtils.decryptText(password);
//        if(content != null) {
//            String decrypt = new String(content);
//            Log.e("TAG", "decrypt password: "+decrypt);
//        }

    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private Key getEncryptKeyFromStore(String alias) {
        try {
            KeyStore ks = KeyStore.getInstance(AndroidKeyStore);
            ks.load(null);
            if(ks.containsAlias(alias)) {
                return ks.getKey(alias, null);
            }
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStore);
            KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(alias,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setKeySize(128)
                    .build();
            keyGenerator.init(spec);
            return keyGenerator.generateKey();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return null;
    }

}

